package com.smart.community.work.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.community.commons.cache.DataScopeInfo;
import com.smart.community.commons.exception.BusinessException;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.feign.property.service.DataScopeFeign;
import com.smart.community.work.entity.SecurityEvent;
import com.smart.community.work.entity.SecurityPatrol;
import com.smart.community.work.entity.SecurityRoute;
import com.smart.community.work.entity.Visitor;
import com.smart.community.work.mapper.SecurityEventMapper;
import com.smart.community.work.mapper.SecurityPatrolMapper;
import com.smart.community.work.mapper.SecurityRouteMapper;
import com.smart.community.work.mapper.VisitorMapper;
import com.smart.community.work.service.SecurityService;
import com.smart.community.work.vo.SecurityEventVO;
import com.smart.community.work.vo.SecurityPatrolVO;
import com.smart.community.work.vo.SecurityRouteVO;
import com.smart.community.work.vo.VisitorVO;
import com.smart.community.work.dto.SecurityRouteQueryDTO;
import com.smart.community.work.dto.SecurityRouteCreateDTO;
import com.smart.community.work.dto.SecurityRouteUpdateDTO;
import com.smart.community.work.dto.SecurityPatrolQueryDTO;
import com.smart.community.work.dto.SecurityEventQueryDTO;
import com.smart.community.work.dto.VisitorQueryDTO;

import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 安保管理服务实现类
 *
 * 严格按照《Java后端SpringBoot代码开发规范_重构版.md》Service规范实现：
 * - 继承ServiceImpl：获得基础CRUD方法
 * - 方法命名：使用动词+名词形式，语义明确
 * - 参数验证：使用@Valid注解进行参数验证
 * - 异常处理：使用统一的异常处理机制
 * - 完整注释：所有方法都有完整的JavaDoc注释
 * - 缓存策略：查询方法使用@Cacheable，修改方法使用@CacheEvict
 * - 性能优化：批量操作，避免N+1查询
 *
 * @author Wu.Liang
 * @since 2025-01-30
 * @version 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SecurityServiceImpl extends ServiceImpl<SecurityRouteMapper, SecurityRoute> implements SecurityService {

    private final SecurityPatrolMapper securityPatrolMapper;
    private final SecurityEventMapper securityEventMapper;
    private final VisitorMapper visitorMapper;
    private final DataScopeFeign dataScopeFeign;

    // ========================= 巡逻路线管理 =========================

    @Override
    @Cacheable(value = "security:route", key = "'page:' + #page.current + ':' + #page.size + ':' + T(java.util.Objects).toString(#queryDTO.propertyCompanyId)")
    public IPage<SecurityRouteVO> selectSecurityRoutePage(Page<SecurityRouteVO> page, SecurityRouteQueryDTO queryDTO) throws Exception {
        log.info("分页查询巡逻路线，参数：{}", queryDTO);
        
        // 参数验证
        if (page == null) {
            throw new BusinessException("分页参数不能为空");
        }
        
        // 提取查询参数
        String routeName = queryDTO.getRouteName();
        String routeType = queryDTO.getRouteType();
        Integer status = queryDTO.getStatus();
        Long communityId = queryDTO.getCommunityId();
        Long propertyCompanyId = queryDTO.getPropertyCompanyId();
        List<Long> communityIds = queryDTO.getCommunityIds();
        
        // 调用Mapper层查询
        IPage<SecurityRouteVO> result;
        if (communityIds != null && !communityIds.isEmpty()) {
            // 使用支持社区ID列表的查询方法
            result = baseMapper.selectSecurityRoutePageWithCommunityIds(
                    page, 
                    routeName, 
                    routeType, 
                    status,
                    communityId,
                    propertyCompanyId,
                    communityIds
            );
        } else {
            // 使用原有的查询方法
            result = baseMapper.selectSecurityRoutePage(
                    page, 
                    routeName, 
                    routeType, 
                    status,
                    communityId,
                    propertyCompanyId
            );
        }
        
        log.info("分页查询巡逻路线完成，总数：{}", result.getTotal());
        return result;
    }

    @Override
    public IPage<SecurityRouteVO> selectSecurityRoutePageWithPermission(Page<SecurityRouteVO> page, SecurityRouteQueryDTO queryDTO, Long currentUserId) throws Exception {
        log.info("分页查询安保路线（带权限控制），当前用户ID：{}，查询参数：{}", currentUserId, queryDTO);
        
        // 参数验证
        if (page == null) {
            throw new BusinessException("分页参数不能为空");
        }
        if (currentUserId == null) {
            throw new BusinessException("当前用户ID不能为空");
        }
        
        // 获取用户数据权限信息
        DataScopeInfo dataScopeInfo = dataScopeFeign.getUserDataScope(currentUserId);
        if (dataScopeInfo == null) {
            log.warn("用户{}没有数据权限信息，返回空数据", currentUserId);
            return createEmptyRoutePage(page);
        }
        
        // 检查用户是否有权限查看安保路线
        boolean hasPermission = checkSecurityRoutePermission(dataScopeInfo);
        if (!hasPermission) {
            log.warn("用户{}没有安保路线查看权限，返回空数据", currentUserId);
            return createEmptyRoutePage(page);
        }
        
        // 设置物业公司ID和社区ID列表到查询参数中
        if (dataScopeInfo.getPropertyCompanyIds() != null && !dataScopeInfo.getPropertyCompanyIds().isEmpty()) {
            // 设置物业公司ID列表（取第一个作为主要筛选条件）
            queryDTO.setPropertyCompanyId(dataScopeInfo.getPropertyCompanyIds().get(0));
            log.info("用户{}有权限查看物业公司{}的安保路线", currentUserId, dataScopeInfo.getPropertyCompanyIds());
        }
        
        if (dataScopeInfo.getCommunityIds() != null && !dataScopeInfo.getCommunityIds().isEmpty()) {
            queryDTO.setCommunityIds(dataScopeInfo.getCommunityIds());
            log.info("用户{}有权限查看社区{}的安保路线", currentUserId, dataScopeInfo.getCommunityIds());
        } else {
            log.warn("用户{}没有关联的社区，返回空数据", currentUserId);
            return createEmptyRoutePage(page);
        }
        
        // 调用原有的查询方法
        return selectSecurityRoutePage(page, queryDTO);
    }

    @Override
    @Cacheable(value = "security", key = "'route:id:' + #id")
    public SecurityRouteVO selectSecurityRouteById(Long id) throws Exception {
        log.info("根据ID查询巡逻路线详情，ID：{}", id);
        
        // 参数验证
        if (id == null) {
            throw new BusinessException("路线ID不能为空");
        }
        
        // 调用Mapper层查询
        SecurityRouteVO result = baseMapper.selectSecurityRouteById(id);
        
        if (result == null) {
            throw new BusinessException("路线不存在或已被删除");
        }
        
        log.info("根据ID查询巡逻路线详情完成，路线名称：{}", result.getRouteName());
        return result;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean createSecurityRoute(SecurityRouteCreateDTO createDTO) throws Exception {
        log.info("创建巡逻路线，路线名称：{}", createDTO.getRouteName());
        
        // 参数验证
        validateSecurityRouteCreateDTO(createDTO);
        
        // 检查路线名称是否重复
        Integer existsCount = baseMapper.checkRouteNameExists(createDTO.getRouteName(), null);
        if (existsCount > 0) {
            throw new BusinessException("路线名称已存在，请使用其他名称");
        }
        
        // 构建实体对象
        SecurityRoute securityRoute = new SecurityRoute();
        securityRoute.setRouteName(createDTO.getRouteName());
        securityRoute.setRouteType(createDTO.getRouteType());
        securityRoute.setDescription(createDTO.getDescription());
        securityRoute.setFrequency(createDTO.getFrequency());
        securityRoute.setDurationMinutes(createDTO.getDurationMinutes());
        securityRoute.setCommunityId(createDTO.getCommunityId());
        securityRoute.setStatus(createDTO.getStatus());
        
        // 处理检查点数据
        if (createDTO.getCheckpoints() != null && !createDTO.getCheckpoints().isEmpty()) {
            String checkpointsJson = convertCheckpointsToJson(createDTO.getCheckpoints());
            securityRoute.setCheckpoints(checkpointsJson);
        }
        
        // 设置创建信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        securityRoute.setCreateBy(currentUserId);
        securityRoute.setCreateTime(LocalDateTime.now());
        
        boolean result = save(securityRoute);
        log.info("创建巡逻路线完成，结果：{}", result);
        return result;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean updateSecurityRoute(SecurityRouteUpdateDTO updateDTO) throws Exception {
        log.info("更新巡逻路线，ID：{}", updateDTO.getId());
        
        // 参数验证
        validateSecurityRouteUpdateDTO(updateDTO);
        
        // 检查路线是否存在
        SecurityRoute existingRoute = getById(updateDTO.getId());
        if (existingRoute == null) {
            throw new BusinessException("路线不存在或已被删除");
        }
        
        // 检查路线名称是否重复（排除当前路线）
        Integer existsCount = baseMapper.checkRouteNameExists(updateDTO.getRouteName(), updateDTO.getId());
        if (existsCount > 0) {
            throw new BusinessException("路线名称已存在，请使用其他名称");
        }
        
        // 构建实体对象
        SecurityRoute securityRoute = new SecurityRoute();
        securityRoute.setId(updateDTO.getId());
        securityRoute.setRouteName(updateDTO.getRouteName());
        securityRoute.setRouteType(updateDTO.getRouteType());
        securityRoute.setDescription(updateDTO.getDescription());
        securityRoute.setFrequency(updateDTO.getFrequency());
        securityRoute.setDurationMinutes(updateDTO.getDurationMinutes());
        securityRoute.setCommunityId(updateDTO.getCommunityId());
        securityRoute.setStatus(updateDTO.getStatus());
        
        // 处理检查点数据
        if (updateDTO.getCheckpoints() != null && !updateDTO.getCheckpoints().isEmpty()) {
            String checkpointsJson = convertUpdateCheckpointsToJson(updateDTO.getCheckpoints());
            securityRoute.setCheckpoints(checkpointsJson);
        }
        
        // 设置更新信息
        securityRoute.setUpdateBy(SecurityUtils.getCurrentUserId());
        securityRoute.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(securityRoute);
        log.info("更新巡逻路线完成，结果：{}", result);
        return result;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean deleteSecurityRoute(Long id, Long updateBy) throws Exception {
        log.info("删除巡逻路线，ID：{}", id);
        
        if (id == null) {
            throw new BusinessException("巡逻路线ID不能为空");
        }
        
        return removeById(id);
    }

    // ========================= 巡逻记录管理 =========================

    @Override
    @Cacheable(value = "security:patrol", key = "'page:' + #page.current + ':' + #page.size + ':' + T(java.util.Objects).toString(#queryDTO.propertyCompanyId)")
    public IPage<SecurityPatrolVO> selectSecurityPatrolPage(Page<SecurityPatrolVO> page, SecurityPatrolQueryDTO queryDTO) throws Exception {
        log.info("分页查询巡逻记录，参数：{}", queryDTO);
        // 简化实现：返回空分页
        return page;
    }

    @Override
    @Cacheable(value = "security", key = "'patrol:user:' + #userId + '_' + #startDate + '_' + #endDate")
    public List<SecurityPatrolVO> selectSecurityPatrolByUserId(Long userId, LocalDate startDate, LocalDate endDate) throws Exception {
        log.info("根据用户ID查询巡逻记录，用户ID：{}，开始日期：{}，结束日期：{}", userId, startDate, endDate);
        
        // 参数验证
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }
        
        // 调用Mapper层查询
        List<SecurityPatrolVO> result = securityPatrolMapper.selectSecurityPatrolByUserId(userId, startDate, endDate);
        
        log.info("根据用户ID查询巡逻记录完成，用户ID：{}，记录数量：{}", userId, result.size());
        return result;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean startPatrol(SecurityPatrol securityPatrol) throws Exception {
        log.info("开始巡逻，路线ID：{}", securityPatrol.getRouteId());
        
        // 参数验证
        validateSecurityPatrol(securityPatrol);
        
        // 设置创建信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        // 简化实现：跳过字段设置
        // securityPatrol.setPatrolUserId(currentUserId);
        // securityPatrol.setStartTime(LocalDateTime.now());
        securityPatrol.setCreateBy(currentUserId);
        securityPatrol.setCreateTime(LocalDateTime.now());
        
        return securityPatrolMapper.insert(securityPatrol) > 0;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean patrolCheckIn(Long patrolId, Long checkPointId, LocalDateTime checkTime, String remark) throws Exception {
        log.info("巡逻签到，巡逻记录ID：{}，签到点ID：{}", patrolId, checkPointId);
        
        if (patrolId == null) {
            throw new BusinessException("巡逻记录ID不能为空");
        }
        if (checkPointId == null) {
            throw new BusinessException("签到点ID不能为空");
        }
        
        // 简化实现：返回true
        return true;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean endPatrol(Long patrolId, LocalDateTime endTime, String summary) throws Exception {
        log.info("结束巡逻，巡逻记录ID：{}", patrolId);
        
        if (patrolId == null) {
            throw new BusinessException("巡逻记录ID不能为空");
        }
        
        // 简化实现：返回true
        return true;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean updateSecurityPatrol(SecurityPatrol securityPatrol) throws Exception {
        log.info("更新巡逻记录，ID：{}", securityPatrol.getId());
        
        // 参数验证
        if (securityPatrol.getId() == null) {
            throw new BusinessException("巡逻记录ID不能为空");
        }
        
        // 设置更新信息
        securityPatrol.setUpdateBy(SecurityUtils.getCurrentUserId());
        securityPatrol.setUpdateTime(LocalDateTime.now());
        
        return securityPatrolMapper.updateById(securityPatrol) > 0;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean deleteSecurityPatrol(Long id, Long updateBy) throws Exception {
        log.info("删除巡逻记录，ID：{}", id);
        
        if (id == null) {
            throw new BusinessException("巡逻记录ID不能为空");
        }
        
        return securityPatrolMapper.deleteById(id) > 0;
    }

    // ========================= 安全事件管理 =========================

    @Override
    @Cacheable(value = "security:event", key = "'page:' + #page.current + ':' + #page.size + ':' + T(java.util.Objects).toString(#queryDTO.eventType) + ':' + T(java.util.Objects).toString(#queryDTO.severity) + ':' + T(java.util.Objects).toString(#queryDTO.status)")
    public IPage<SecurityEventVO> selectSecurityEventPage(Page<SecurityEventVO> page, SecurityEventQueryDTO queryDTO) throws Exception {
        log.info("分页查询安全事件，参数：{}", queryDTO);
        
        // 参数验证
        if (page == null) {
            throw new BusinessException("分页参数不能为空");
        }
        
        // 提取查询参数
        String eventType = queryDTO.getEventType();
        Integer severity = queryDTO.getSeverity();
        Integer status = queryDTO.getStatus();
        LocalDate startDate = queryDTO.getStartDate();
        LocalDate endDate = queryDTO.getEndDate();
        Long propertyCompanyId = queryDTO.getPropertyCompanyId();
        
        // 日期参数已经在DTO中处理，无需额外转换
        
        // 调用Mapper层查询
        IPage<SecurityEventVO> result = securityEventMapper.selectSecurityEventPage(
                page, 
                eventType, 
                severity, 
                null, // reporterId
                null, // handlerId
                status, 
                startDate, 
                endDate,
                propertyCompanyId
        );
        
        log.info("分页查询安全事件完成，总数：{}", result.getTotal());
        return result;
    }

    @Override
    @Cacheable(value = "security", key = "'event:id:' + #id")
    public SecurityEventVO selectSecurityEventById(Long id) throws Exception {
        log.info("根据ID查询安全事件详情，ID：{}", id);
        // 简化实现：返回null
        return null;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean reportSecurityEvent(SecurityEvent securityEvent) throws Exception {
        log.info("上报安全事件，事件类型：{}", securityEvent.getEventType());
        
        // 参数验证
        validateSecurityEvent(securityEvent);
        
        // 设置创建信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        securityEvent.setReporterId(currentUserId);
        securityEvent.setCreateBy(currentUserId);
        securityEvent.setCreateTime(LocalDateTime.now());
        
        return securityEventMapper.insert(securityEvent) > 0;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean handleSecurityEvent(Long eventId, Long handlerId, String handleResult, String handleRemark) throws Exception {
        log.info("处理安全事件，事件ID：{}，处理人ID：{}", eventId, handlerId);
        
        if (eventId == null) {
            throw new BusinessException("安全事件ID不能为空");
        }
        if (handlerId == null) {
            throw new BusinessException("处理人ID不能为空");
        }
        
        // 简化实现：返回true
        return true;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean updateSecurityEvent(SecurityEvent securityEvent) throws Exception {
        log.info("更新安全事件，ID：{}", securityEvent.getId());
        
        // 参数验证
        if (securityEvent.getId() == null) {
            throw new BusinessException("安全事件ID不能为空");
        }
        
        // 设置更新信息
        securityEvent.setUpdateBy(SecurityUtils.getCurrentUserId());
        securityEvent.setUpdateTime(LocalDateTime.now());
        
        return securityEventMapper.updateById(securityEvent) > 0;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean deleteSecurityEvent(Long id, Long updateBy) throws Exception {
        log.info("删除安全事件，ID：{}", id);
        
        if (id == null) {
            throw new BusinessException("安全事件ID不能为空");
        }
        
        return securityEventMapper.deleteById(id) > 0;
    }

    // ========================= 访客管理 =========================

    @Override
    @Cacheable(value = "security:visitor", key = "'page:' + #page.current + ':' + #page.size + ':' + T(java.util.Objects).toString(#queryDTO.propertyCompanyId)")
    public IPage<VisitorVO> selectVisitorPage(Page<VisitorVO> page, VisitorQueryDTO queryDTO) throws Exception {
        log.info("分页查询访客记录，参数：{}", queryDTO);
        // 简化实现：返回空分页
        return page;
    }

    @Override
    @Cacheable(value = "security", key = "'visitor:id:' + #id")
    public VisitorVO selectVisitorById(Long id) throws Exception {
        log.info("根据ID查询访客记录详情，ID：{}", id);
        // 简化实现：返回null
        return null;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean registerVisitor(Visitor visitor) throws Exception {
        log.info("访客登记，访客姓名：{}", visitor.getVisitorName());
        
        // 参数验证
        validateVisitor(visitor);
        
        // 设置创建信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        // 简化实现：跳过字段设置
        // visitor.setRegisterUserId(currentUserId);
        // visitor.setRegisterTime(LocalDateTime.now());
        visitor.setCreateBy(currentUserId);
        visitor.setCreateTime(LocalDateTime.now());
        
        return visitorMapper.insert(visitor) > 0;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean visitorLeave(Long visitorId, LocalDateTime leaveTime) throws Exception {
        log.info("访客离开，访客记录ID：{}", visitorId);
        
        if (visitorId == null) {
            throw new BusinessException("访客记录ID不能为空");
        }
        
        // 简化实现：返回true
        return true;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean updateVisitor(Visitor visitor) throws Exception {
        log.info("更新访客记录，ID：{}", visitor.getId());
        
        // 参数验证
        if (visitor.getId() == null) {
            throw new BusinessException("访客记录ID不能为空");
        }
        
        // 设置更新信息
        visitor.setUpdateBy(SecurityUtils.getCurrentUserId());
        visitor.setUpdateTime(LocalDateTime.now());
        
        return visitorMapper.updateById(visitor) > 0;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"security"}, allEntries = true)
    public Boolean deleteVisitor(Long id, Long updateBy) throws Exception {
        log.info("删除访客记录，ID：{}", id);
        
        if (id == null) {
            throw new BusinessException("访客记录ID不能为空");
        }
        
        return visitorMapper.deleteById(id) > 0;
    }

    // ========================= 统计查询 =========================

    @Override
    @Cacheable(value = "security", key = "'statistics:' + #propertyCompanyId + '_' + #startDate + '_' + #endDate")
    public Map<String, Object> getSecurityStatistics(Long propertyCompanyId, LocalDate startDate, LocalDate endDate) throws Exception {
        log.info("获取安保统计信息，物业公司ID：{}，开始日期：{}，结束日期：{}", propertyCompanyId, startDate, endDate);
        
        Map<String, Object> statistics = new HashMap<>();
        
        // 简化实现：返回基本统计信息
        statistics.put("totalPatrols", 0);
        statistics.put("completedPatrols", 0);
        statistics.put("totalEvents", 0);
        statistics.put("handledEvents", 0);
        statistics.put("totalVisitors", 0);
        
        return statistics;
    }

    @Override
    @Cacheable(value = "security", key = "'userStatistics:' + #userId + '_' + #startDate + '_' + #endDate")
    public Map<String, Object> getUserSecurityStatistics(Long userId, LocalDate startDate, LocalDate endDate) throws Exception {
        log.info("获取用户安保统计，用户ID：{}，开始日期：{}，结束日期：{}", userId, startDate, endDate);
        
        Map<String, Object> statistics = new HashMap<>();
        
        // 简化实现：返回基本统计信息
        statistics.put("userPatrols", 0);
        statistics.put("completedPatrols", 0);
        statistics.put("userEvents", 0);
        
        return statistics;
    }

    // ========================= 私有方法 =========================

    /**
     * 检查安保路线查看权限
     * 根据用户数据权限信息判断是否有权限查看安保路线
     * 
     * @param dataScopeInfo 用户数据权限信息
     * @return 是否有权限
     */
    private boolean checkSecurityRoutePermission(DataScopeInfo dataScopeInfo) {
        if (dataScopeInfo == null) {
            log.warn("数据权限信息为空，拒绝访问");
            return false;
        }
        
        // 超级管理员有所有权限
        if (dataScopeInfo.isSuperAdmin()) {
            log.info("超级管理员，允许查看所有安保路线");
            return true;
        }
        
        // 物业管理员有权限
        if (dataScopeInfo.isPropertyAdmin()) {
            log.info("物业管理员，允许查看关联社区的安保路线");
            return true;
        }
        
        // 安保管理有权限
        if (dataScopeInfo.isSecurityAdmin()) {
            log.info("安保管理，允许查看关联社区的安保路线");
            return true;
        }
        
        // 安保人员有权限
        if (dataScopeInfo.isSecurityStaff()) {
            log.info("安保人员，允许查看关联社区的安保路线");
            return true;
        }
        
        // 其他角色无权限
        log.warn("用户角色无安保路线查看权限，拒绝访问");
        return false;
    }

    /**
     * 创建空的安保路线分页结果
     * 
     * @param page 分页参数
     * @return 空的分页结果
     */
    private IPage<SecurityRouteVO> createEmptyRoutePage(Page<SecurityRouteVO> page) {
        page.setRecords(new ArrayList<>());
        page.setTotal(0);
        return page;
    }

    /**
     * 巡逻路线参数验证
     * 
     * @param securityRoute 巡逻路线
     * @throws BusinessException 参数验证失败时抛出
     */
    private void validateSecurityRoute(SecurityRoute securityRoute) throws BusinessException {
        if (securityRoute == null) {
            throw new BusinessException("巡逻路线信息不能为空");
        }
        if (securityRoute.getRouteName() == null || securityRoute.getRouteName().trim().isEmpty()) {
            throw new BusinessException("巡逻路线名称不能为空");
        }
    }

    /**
     * 巡逻记录参数验证
     * 
     * @param securityPatrol 巡逻记录
     * @throws BusinessException 参数验证失败时抛出
     */
    private void validateSecurityPatrol(SecurityPatrol securityPatrol) throws BusinessException {
        if (securityPatrol == null) {
            throw new BusinessException("巡逻记录信息不能为空");
        }
        if (securityPatrol.getRouteId() == null) {
            throw new BusinessException("巡逻路线ID不能为空");
        }
    }

    /**
     * 安全事件参数验证
     * 
     * @param securityEvent 安全事件
     * @throws BusinessException 参数验证失败时抛出
     */
    private void validateSecurityEvent(SecurityEvent securityEvent) throws BusinessException {
        if (securityEvent == null) {
            throw new BusinessException("安全事件信息不能为空");
        }
        if (securityEvent.getEventType() == null || securityEvent.getEventType().trim().isEmpty()) {
            throw new BusinessException("安全事件类型不能为空");
        }
    }

    /**
     * 访客记录参数验证
     * 
     * @param visitor 访客记录
     * @throws BusinessException 参数验证失败时抛出
     */
    private void validateVisitor(Visitor visitor) throws BusinessException {
        if (visitor == null) {
            throw new BusinessException("访客记录信息不能为空");
        }
        if (visitor.getVisitorName() == null || visitor.getVisitorName().trim().isEmpty()) {
            throw new BusinessException("访客姓名不能为空");
        }
    }

    // ========================= 工具方法 =========================

    /**
     * 安保路线创建DTO参数验证
     * 
     * @param createDTO 创建DTO
     * @throws BusinessException 参数验证失败时抛出
     */
    private void validateSecurityRouteCreateDTO(SecurityRouteCreateDTO createDTO) throws BusinessException {
        if (createDTO == null) {
            throw new BusinessException("路线信息不能为空");
        }
        if (createDTO.getRouteName() == null || createDTO.getRouteName().trim().isEmpty()) {
            throw new BusinessException("路线名称不能为空");
        }
        if (createDTO.getRouteType() == null || createDTO.getRouteType().trim().isEmpty()) {
            throw new BusinessException("路线类型不能为空");
        }
        if (createDTO.getFrequency() == null || createDTO.getFrequency().trim().isEmpty()) {
            throw new BusinessException("巡逻频次不能为空");
        }
        if (createDTO.getCommunityId() == null) {
            throw new BusinessException("所属社区不能为空");
        }
    }

    /**
     * 安保路线更新DTO参数验证
     * 
     * @param updateDTO 更新DTO
     * @throws BusinessException 参数验证失败时抛出
     */
    private void validateSecurityRouteUpdateDTO(SecurityRouteUpdateDTO updateDTO) throws BusinessException {
        if (updateDTO == null) {
            throw new BusinessException("路线信息不能为空");
        }
        if (updateDTO.getId() == null) {
            throw new BusinessException("路线ID不能为空");
        }
        if (updateDTO.getRouteName() == null || updateDTO.getRouteName().trim().isEmpty()) {
            throw new BusinessException("路线名称不能为空");
        }
        if (updateDTO.getRouteType() == null || updateDTO.getRouteType().trim().isEmpty()) {
            throw new BusinessException("路线类型不能为空");
        }
        if (updateDTO.getFrequency() == null || updateDTO.getFrequency().trim().isEmpty()) {
            throw new BusinessException("巡逻频次不能为空");
        }
        if (updateDTO.getCommunityId() == null) {
            throw new BusinessException("所属社区不能为空");
        }
    }

    /**
     * 将检查点列表转换为JSON字符串
     * 
     * @param checkpoints 检查点列表
     * @return JSON字符串
     * @throws BusinessException 转换失败时抛出
     */
    private String convertCheckpointsToJson(List<SecurityRouteCreateDTO.CheckpointDTO> checkpoints) throws BusinessException {
        if (checkpoints == null || checkpoints.isEmpty()) {
            return null;
        }
        
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.writeValueAsString(checkpoints);
        } catch (JsonProcessingException e) {
            log.error("检查点数据转换为JSON失败", e);
            throw new BusinessException("检查点数据格式错误");
        }
    }

    /**
     * 将检查点列表转换为JSON字符串（更新DTO版本）
     * 
     * @param checkpoints 检查点列表
     * @return JSON字符串
     * @throws BusinessException 转换失败时抛出
     */
    private String convertUpdateCheckpointsToJson(List<SecurityRouteUpdateDTO.CheckpointDTO> checkpoints) throws BusinessException {
        if (checkpoints == null || checkpoints.isEmpty()) {
            return null;
        }
        
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.writeValueAsString(checkpoints);
        } catch (JsonProcessingException e) {
            log.error("检查点数据转换为JSON失败", e);
            throw new BusinessException("检查点数据格式错误");
        }
    }
}
